
import json
import logging
import logging.handlers

from websocket_server import WebsocketServer

from my_client import MyClient


class MyServer:
    def __init__(self, port):
        self.server = WebsocketServer(host='', port=port)

        self.server.set_fn_new_client(self.on_new_client)
        self.server.set_fn_client_left(self.on_client_left)
        self.server.set_fn_message_received(self.on_message_received)

        self.my_clients = {}

    def send_message(self, client, msg_type, msg_body):
        """Send message to client or all clients if client is none"""

        logging.info(f"MyServer.send_message, client = {client}, msgType={msg_type}, msgBody={msg_body}")

        message = {
            'type': msg_type,
            'body': msg_body
        }

        message = json.dumps(message)
        if client is not None:
            self.server.send_message(client, message)
            return

        for ws_client in self.my_clients.values():
            self.server.send_message(ws_client.client, message)

    def on_new_client(self, client, server):
        """New client handle function"""

        logging.info(f"MyServer.on_new_client, client = {client}")

        self.my_clients[client['id']] = MyClient(self, client)

    def on_client_left(self, client, server):
        """Client left handle function"""

        logging.info(f"MyServer.on_client_left, client = {client}")

        del self.my_clients[client['id']]

    def on_message_received(self, client, server, message):
        """Message received handle function"""

        message = json.loads(message)
        msg_type = message['type']
        msg_body = message['body']

        logging.info(f"MyServer.on_message_received, client = {client}, msgType={msg_type}, msgBody={msg_body}")

        ws_client = self.my_clients.get(client['id'], None)
        if ws_client is not None:
            ws_client.on_message_received(msg_type, msg_body)

    def start(self, threaded):
        logging.info(f"MyServer.start")

        self.server.run_forever(threaded)


if __name__ == '__main__':
    handler = logging.handlers.TimedRotatingFileHandler(
        filename='my_server.log',
        when="midnight",
        interval=1,
        encoding="utf=8"
    )

    logging.basicConfig(level=logging.INFO, format='%(asctime)s | %(levelname)s | %(message)s',
                        handlers=[handler])

    ws_server = MyServer(9999)    
    ws_server.start(threaded=False)
